package top.vanchor.flexible.utils;

import cn.hutool.core.util.StrUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import top.vanchor.flexible.config.initexception.BusinessException;
import top.vanchor.flexible.config.initexception.ErrorEnum;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : 98523
 * @create 2023/5/20 11:25
 */
public class ExcelUtils {

    /**
     * 将单元格内容以String类型返回
     *
     * @param cell 单元格
     * @return String类型数据数据
     */
    public static String getCellValueAsString(Cell cell) {
        if (cell == null) {
            return null;
        }
        if (cell.getCellType() == CellType.STRING) {
            return cell.getStringCellValue();
        }
        if (cell.getCellType() == CellType.NUMERIC) {
            return String.valueOf(cell.getNumericCellValue());
        }
        if (cell.getCellType() == CellType.BOOLEAN) {
            return String.valueOf(cell.getBooleanCellValue());
        }
        if (cell.getCellType() == CellType.FORMULA) {
            return cell.getCellFormula();
        }
        return null;
    }

    public static String getCellValueAsStringForce(Cell cell) {
        if (cell == null) {
            return null;
        }
        String res = "";
        if (cell.getCellType() == CellType.STRING) {
            res = cell.getStringCellValue();
        }
        if (cell.getCellType() == CellType.NUMERIC) {
            res =  String.valueOf(cell.getNumericCellValue());
            String regex = ".*E\\d+";
            if (res.matches(regex)){
                //科学计数法，比如1.01433001E9，去除.和E9，得到101433001
                //因为1.01433001E9有9位，但01433001只有8位，后面需要补充0
                int zeroNum = Integer.parseInt(res.split("E")[1]);
                int lookNum = ((res.split("\\.")[1]).split("E")[0]).length();
                res = res.replace(".", "").split("E")[0];
                while (lookNum++ < zeroNum){
                    res += "0";
                }
                return res;
            }
            if (res.contains(".")){
                //说明是小数，比如123243.0->去除.以后的内容
                return res.split("\\.")[0];
            }
        }
        if (cell.getCellType() == CellType.BOOLEAN) {
            res =  String.valueOf(cell.getBooleanCellValue());
        }
        if (cell.getCellType() == CellType.FORMULA) {
            res =  cell.getCellFormula();
        }
        return res;
    }

    public static Double cellToBigDecimal(Cell cell) {
        String str = getCellValueAsString(cell);
        if (str == null || "".equals(str)) {
            return null;
        }
        return BigDecimal.valueOf(Double.parseDouble(str)).doubleValue();
    }

    public static Date cellToDate(Cell cell) {
        String str = getCellValueAsString(cell);
        if (str == null || "".equals(str)) {
            return null;
        }
        String[] dateFormats = {"yyyy-MM-dd", "yyyy/MM/dd","yyyyMMdd"};
        // 遍历支持的日期格式
        for (String dateFormat : dateFormats) {
            DateFormat dft = new SimpleDateFormat(dateFormat);
            try {
                return dft.parse(str);
            } catch (ParseException e) {
                // 忽略异常，继续尝试下一个格式
            }
        }
        //第一级如果不行，再看看是否是“45429.0”这种格式
        // 判断字符串是否是数字
        if (isNumeric(str)) {
            // 转换成 double 类型
            double excelSerialDate = Double.parseDouble(str);
            return convertExcelSerialDateToJavaDate(excelSerialDate);
        }
        // 如果没有任何格式匹配，则抛出异常
        throw new BusinessException(ErrorEnum.DATE_ANALYSIS_ERR);
    }

    public static BigDecimal stringToDecimal(String str) {
        if (StrUtil.isEmpty(str)){
            return null;
        }
        return BigDecimal.valueOf(Double.parseDouble(str.replace(",","")));
    }

    public static BigDecimal getCellParseBigDecimalAsString(Cell cell) {
        if (cell == null) {
            return null;
        }
        String str = getCellValueAsString(cell);
        if (StrUtil.isEmpty(str)){
            return null;
        }
        return BigDecimal.valueOf(Double.parseDouble(str.replace(",","")));
    }

    public static Integer parseInteger(Cell cell) {
        if (cell == null) {
            return null;
        }
        String str = getCellValueAsString(cell);
        if (StrUtil.isEmpty(str)){
            return null;
        }
        try {
            return Integer.parseInt(str);
            // 整数解析成功，处理整数
        } catch (NumberFormatException e) {
            // 整数解析失败，尝试解析为浮点数
            return (int) Double.parseDouble(str);
            // 浮点数解析成功，处理浮点数
        }
    }

    // 判断字符串是否是数字
    public static boolean isNumeric(String str) {
        try {
            Double.parseDouble(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    // 将Excel中的时间序列号转换成Java的Date对象
    public static Date convertExcelSerialDateToJavaDate(double serialDate) {
        // Excel的时间序列号起始日期为1900年1月1日
        Calendar calendar = Calendar.getInstance();
        calendar.set(1900, Calendar.JANUARY, 1); // 设置为1900年1月1日

        // Excel中的时间序列号包括了整天的部分和小数部分（小时、分钟、秒）
        int days = (int) serialDate; // 获取整天部分
        double fraction = serialDate - days; // 获取小数部分
        int hours = (int) (fraction * 24); // 小时部分
        int minutes = (int) ((fraction * 24 - hours) * 60); // 分钟部分
        int seconds = (int) ((((fraction * 24 - hours) * 60) - minutes) * 60); // 秒部分

        // 加上对应的天数和时间
        calendar.add(Calendar.DAY_OF_YEAR, days - 1);
        calendar.add(Calendar.HOUR_OF_DAY, hours);
        calendar.add(Calendar.MINUTE, minutes);
        calendar.add(Calendar.SECOND, seconds);

        return calendar.getTime();
    }

    public static Integer getCellValueAsInteger(Cell cell) {
        String str = ExcelUtils.getCellValueAsString(cell);
        //砍掉所有小数点
        if (str.contains(".")){
            str = str.split("\\.")[0];
        }
        return Integer.parseInt(str);
    }
}
